/*
 * Copyright (C) 2016 Lokiy(liulongke@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  　　　　http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.lokiy.databinding

import androidx.databinding.BindingAdapter
import androidx.lifecycle.ViewModel
import androidx.lifecycle.isLoading
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.lokiy.core.adapter.BasicAdapter
import com.lokiy.core.vm.BasicListViewModel
import com.lokiy.databinding.adapter.BasicDataBindingAdapter
import com.lokiy.databinding.adapter.VMDataBindingAdapter

/**
 * RecyclerBinding
 * @author Lokiy
 * 2021-02-22 9:15
 */
object RecyclerBinding {

    /**
     * Bind data to RecyclerView.
     */
    @JvmStatic
    @Suppress("UNCHECKED_CAST")
    @BindingAdapter(value = ["listData", "vm", "layoutId"], requireAll = false)
    fun <T> bindData(recyclerView: RecyclerView, data: List<T>?, viewModel: ViewModel?, layoutId: Int = 0) {
        if (layoutId == 0 && data?.isNotEmpty() == true && data.getOrNull(0) !is BasicDataBindingAdapter.IItemType) {
            throw IllegalArgumentException("RecyclerView's itemLayout is null, please usd layoutId=\"@{xxx}\" or implement BasicDataBindingAdapter.IItemType")
        }
        if (recyclerView.layoutManager == null) {
            recyclerView.layoutManager = LinearLayoutManager(recyclerView.context)
        }
        val adapter: BasicAdapter<T?> = (recyclerView.adapter as BasicAdapter<T?>?) ?: run {
            val loadMore =  { if (viewModel is BasicListViewModel) viewModel.loadMore() }
            val emptyData = BasicDataBindingAdapter.EmptyData(emptyImage ?: 0, emptyText ?: "")
            VMDataBindingAdapter<T>(emptyData, loadMore, layoutId, viewModel).also {
                recyclerView.adapter = it
            }
        }
        if (adapter is VMDataBindingAdapter<*> && viewModel != null) {
            adapter.ensureViewModel(viewModel)
        }

        if (viewModel is BasicListViewModel) {
            val isLoading = viewModel.isInLoading.get()
            adapter.isOnLoadMore = isLoading

            if (viewModel.getCurrentPageIndex() == 1) {
                adapter.refresh(data)
            } else {
                adapter.addAll(data)
            }
        } else {
            adapter.refresh(data)
        }
    }

    /**
     * Adapter footer loading status
     */
    @JvmStatic
    @BindingAdapter(*["adapter", "isLoading"], requireAll = false)
    fun setAdapter(recyclerView: RecyclerView, adapter: com.lokiy.core.adapter.BasicAdapter<*>?, isLoading: Boolean) {
        if (recyclerView.adapter != adapter) {
            recyclerView.adapter = adapter
        }
        adapter ?: return
        adapter.isOnLoadMore = isLoading
        adapter.notifyItemChanged(adapter.itemCount - 1)
    }
}